﻿#ifndef __AVOID_HEAD_FILE_CONTROL_INTERFACE_DRAGSUP_INCLUDE_DUSD__
#define __AVOID_HEAD_FILE_CONTROL_INTERFACE_DRAGSUP_INCLUDE_DUSD__
#include "../control.h"

namespace swui
{
	// overload mouse
	struct ctlNotifyDrag
	{
		enum { begin, end, move } state;
		bool* isAllow;		//是否允许执行通告（针对 begin 和 move）
		ctlPoint position;	//控件将要移动的位置
		ctlPoint mousePos;	//鼠标位置
	};

	class IDrag : virtual public ctlRoot
	{
	public:
		IDrag();
	public:
		void enableDrag(bool = true);
		bool isDragable();
	public:
		// 设置拖放的方向，x 表示横向，y 表示纵向，xy 表示任意方向
		void setDragableDir(ctlDirection dir);
		ctlDirection getDragableDir();
	public:
		//设置是否限制拖动区域
		void limitDragableRange(bool);
		bool limitDragableRange();
		void setDragableRect(ctlRect);
		ctlRect getDragableRect();
	public:
		/* 设置控件在拖动时发现超出拖动区域的的处理方法（默认 true）
		 * 若为 true 那么会自动校正在区域内 
		 * 若为 false 则不会发生改变 
		 * 这可以用在边界上，前一种在边界时很容易就可以碰到
		 * 但是如果人工 move 出区域，那么再拖动则会又回到区域内
		 * 后一种有可能比较不容易碰到边界，但是没有前一种的缺点 */
		void dragDealOverRange(bool);
		bool dragDealOverRange();
	protected:
		virtual void _mouse_event_(ctlMouseEvent*);
	private:
		bool _drag_enable, _drag_moving, _drag_limit_range;
		bool _drag_dealoverrange;
		ctlDirection _drag_dir;
		ctlRect _drag_rect;
		ctlPoint _drag_rawpos, _drag_rawmouse;
	};

	inline void IDrag::enableDrag(bool enable) {
		setDragableDir(ctlDirection::xy);
		setDragableRect(getRect());
		_drag_enable = enable;
		_drag_moving = false;
		_drag_dealoverrange = true;
		_drag_limit_range = false;
	}
	inline bool IDrag::limitDragableRange() { 
		return _drag_limit_range;
	}
	inline void IDrag::limitDragableRange(bool limit) {
		_drag_limit_range = limit;
	}
	inline IDrag::IDrag() : _drag_enable(false), _drag_moving(false) {}
	inline bool IDrag::isDragable() {
		return _drag_enable;
	}
	inline void IDrag::setDragableDir(ctlDirection dir) {
		_drag_dir = dir;
	}
	inline ctlDirection IDrag::getDragableDir() {
		return _drag_dir;
	}
	inline void IDrag::setDragableRect(ctlRect rect) {
		_drag_rect = rect;
		limitDragableRange(true);
	}
	inline ctlRect IDrag::getDragableRect() {
		return _drag_rect;
	}
}

#endif